﻿using CJiaBao.Core.Utils;
using Core.Configuration.Api;
using Core.Configuration.Config;
using Core.Sdk.WeiXin;
using IconYuan.Api.Services;
using IconYuan.Manager.Articles;
using IconYuan.Manager.Markets;
using IconYuan.Manager.Users;
using IconYuan.Model.DB;
using IconYuan.Model.DTO.Users;
using IconYuan.Model.Entity.Articles;
using IconYuan.Model.Entity.Markets;
using IconYuan.Model.Entity.Users;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace IconYuan.Api.Controllers.Users
{
    /// <summary>
    /// 用户操作
    /// </summary>
    public class UserController: ApiBase
    {
        readonly UserManager userSvc;
        readonly UserDetailManager userDetailSvc;
        readonly UserCouponManager userCouponSvc;
        readonly UserGradeManager gradeSvc;
        readonly ArticleManager articleSvc;
        readonly ArticleCateManager cateSvc;
        readonly PointLogManager pointLogSvc;
        readonly BalanceLogManager balanceLogSvc;
        public UserController()
        {
            userSvc = new UserManager();
            userDetailSvc = new UserDetailManager();
            userCouponSvc = new UserCouponManager();
            gradeSvc = new UserGradeManager();
            articleSvc = new ArticleManager();
            cateSvc = new ArticleCateManager();
            pointLogSvc = new PointLogManager();
            balanceLogSvc = new BalanceLogManager();
        }

        /// <summary>
        /// 用户信息
        /// </summary>
        /// <param name="user_id">用户id</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<UserInfoDto> Get(int user_id)
        {
            var user = await userSvc.GetAsync(user_id);
            var detail = await userDetailSvc.GetAsync(x => x.user_id == user.user_id) ?? new UserDetail() { user_id = user_id };

            //会员等级
            var grade = await gradeSvc.GetAsync(x => x.grade_id == user.grade_id);
            var gradeExt = JsonHelper.ToObject<GradeExt>(grade.ext) ?? new GradeExt();

            //优惠券金额
            var startTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-01"));
            var endTime = startTime.AddYears(1);
            var coupons = await userCouponSvc.GetList(user.user_id, startTime, endTime);
            user.brokerage_ratio = gradeExt.brokerage_ratio;

            user.coupon_money = coupons.Sum(x => x.reduce_price);
            user.avatar = $"{GlobalConfig.CdnDomain}{user.avatar}";
            user.ip_location = GetIpInfo(user.ip);
            return DtoHelper.ToUserInfoDto(user, detail, grade);
        }

        /// <summary>
        /// 修改会员详情
        /// </summary>
        /// <param name="model">修改会员详情，必填项：姓名、性别、生日、收缩压、舒张压等</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpPost]
        public async Task<bool> SetDetail(UserDetail model)
        {
            var user = await userSvc.GetAsync(model.user_id);
            if (user == null) throw new Exception("提交的会员不存在");

            var old = await userDetailSvc.GetAsync(x => x.user_id == model.user_id);
            model.is_real = 1;

            if (old == null)
                await userDetailSvc.InsertAsync(model);
            else
                await userDetailSvc.UpdateByUidAsync(model);
            return true;
        }

        /// <summary>
        /// 积分记录
        /// </summary>
        /// <param name="user_id">会员user_id</param>
        /// <param name="page">当前页</param>
        /// <param name="pageSize">每页几条</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PageList<PointLog>> PointList(int user_id, int page = 1, int pageSize = 15)
        {
           var result= await pointLogSvc.GetPageListAsync(x => x.user_id == user_id, y => y.log_id, OrderByType.Desc);
            return result;
        }

        /// <summary>
        /// 消费金记录,佣金记录
        /// </summary>
        /// <param name="user_id"></param>
        ///  <param name="type">类型: 1消费金记录, 2 佣金记录</param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PageList<BalanceLog>> BalanceList(int user_id, int type, int page = 1, int pageSize = 15)
        {
            if (type == 1)
                return await balanceLogSvc.GetPageListAsync(x => x.user_id == user_id && x.scene < 60, y => y.log_id, OrderByType.Desc);
            if (type == 2)
                return await balanceLogSvc.GetPageListAsync(x => x.user_id == user_id && x.scene == 60, y => y.log_id, OrderByType.Desc);
            return new PageList<BalanceLog>();
        }

        /// <summary>
        /// 优惠券记录
        /// </summary>
        /// <param name="user_id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<UserCoupon>> CouponList(int user_id)
        {
            return await userCouponSvc.GetListAsync(x => x.is_use == 0 && x.user_id == user_id);
        }
        /// <summary>
        /// 我的下级客户列表
        /// </summary>
        /// <param name="user_id">我的uid</param>
        /// <param name="page">当前页</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PageList<UserInfoDto>> ChildList(int user_id, int page = 1,int pageSize=20)
        {
            if (user_id <= 0) return new PageList<UserInfoDto>();
            var userList = await userSvc.GetPageListAsync(x => x.parent_id == user_id, y => y.user_id, OrderByType.Desc, page,pageSize);
            var user_ids = userList.data.Select(x => x.user_id).ToArray();
            var grade_ids = userList.data.Select(x => x.grade_id).ToArray();
            var detailList = await userDetailSvc.GetListAsync(x => user_ids.Contains(x.user_id));
            var gradeList = await gradeSvc.GetListAsync(x => grade_ids.Contains(x.grade_id));

            return FormatUserList(userList, detailList, gradeList, new List<UserCoupon>());
        }

        #region 我的服务
        /// <summary>
        /// 我的服务
        /// </summary>
        /// <param name="article_id">合作共赢的文章id，默认=4</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<object> Services(int article_id = 4)
        {
            string category_ids = "3,4,5";
            var article = await articleSvc.GetAsync(article_id) ?? new Article();
            var cateList = await cateSvc.GetByIdsAsync(category_ids.Split(','));
            return new
            {
                cates = cateList,
                cooperate = new
                {
                    wximage = $"{GlobalConfig.CdnDomain}{article.image_url}",
                    wx = "haohao202231",
                    baktip = article.content
                }
            };
        }
        #endregion

        #region 工作台
        /// <summary>
        /// 用户列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageList<UserInfoDto>> List(ListParamDto model)
        {
            var exp = Expressionable.Create<User>();
            exp.And(x => x.store_id == GetStoreId());
            exp.AndIF(!string.IsNullOrEmpty(model.mobile), x => x.mobile.Contains(model.mobile));

            var userList = await userSvc.GetPageListAsync(exp.ToExpression(), y => y.user_id, OrderByType.Desc, model.page);
            var user_ids = userList.data.Select(x => x.user_id).ToArray();
            var grade_ids = userList.data.Select(x => x.grade_id).ToArray();
            var detailList = await userDetailSvc.GetListAsync(x => user_ids.Contains(x.user_id));
            var gradeList = await gradeSvc.GetListAsync(x => grade_ids.Contains(x.grade_id));
            var couponList = await userCouponSvc.GetListAsync(x => user_ids.Contains(x.user_id));
            //list转换
            var list = userList.data.Select(x =>
            {
                var userDetail = detailList.Find(y => y.user_id == x.user_id) ?? new UserDetail();
                var userGrade = gradeList.Find(y => y.grade_id == x.grade_id);
                x.coupon_money = couponList.Where(y => y.user_id == x.user_id).Sum(y => y.reduce_price);
                x.ip_location = GetIpInfo(x.ip);
                return DtoHelper.ToUserInfoDto(x, userDetail, userGrade);
            }).ToList();
            return new PageList<UserInfoDto>()
            {
                current_page = userList.current_page,
                last_page = userList.last_page,
                per_page = userList.per_page,
                total = userList.total,
                data = list
            };
        }
        /// <summary>
        /// 绑定上级id
        /// </summary>
        /// <param name="user_id">需绑定的用户id</param>
        /// <param name="mobile">上级手机号,必须11位</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> BindParentId(int user_id, string mobile)
        {
            var user = await userSvc.GetAsync(user_id);
            if (user == null) throw new Exception("用户不存在");
            if (user.parent_id > 0) throw new Exception("用户已经存在上级");

            var parent = await userSvc.GetAsync(x => x.mobile == mobile.Trim());
            if (parent == null) throw new Exception("上级不存在");

            return await userSvc.UpdateAsync(x => new User() { parent_id = parent.user_id }, y => y.user_id == user_id);
        }

        private PageList<UserInfoDto> FormatUserList(PageList<User> userList, List<UserDetail> detailList,
            List<UserGrade> gradeList, List<UserCoupon> couponList)
        {
            //list转换
            var list = userList.data.Select(x =>
            {
                var userDetail = detailList.Find(y => y.user_id == x.user_id) ?? new UserDetail();
                var userGrade = gradeList.Find(y => y.grade_id == x.grade_id);
                x.coupon_money = couponList.Where(y => y.user_id == x.user_id).Sum(y => y.reduce_price);
                x.ip_location = GetIpInfo(x.ip);
                return DtoHelper.ToUserInfoDto(x, userDetail, userGrade);
            }).ToList();
            return new PageList<UserInfoDto>()
            {
                current_page = userList.current_page,
                last_page = userList.last_page,
                per_page = userList.per_page,
                total = userList.total,
                data = list
            };
        }
        #endregion             

        /// <summary>
        /// 显示失败的IP列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<object> IpList(int page = 1, int pageSize = 20)
        {
            var list = await userSvc.GetPageListAsync(x => x.ip != "", y => y.user_id, OrderByType.Desc, page, pageSize);
            return list.data.Select(x => new
            {
                user_id = x.user_id,
                ip = x.ip,
                ip_location = GetIpInfo(x.ip)
            }).Where(y => y.ip_location.Length < 5).ToList();
        }
        private string GetIpInfo(string ip)
        {
            var location = GetIpLocation(ip);
            if (string.IsNullOrEmpty(location) && !string.IsNullOrEmpty(ip))
            {
                var geo = MapSdk.GetIpLocation(ip).GetAwaiter().GetResult();
                var ipInfo = geo.ad_info;
                if (ipInfo != null)
                    location = $"中国{ipInfo.province}{ipInfo.city}{ipInfo.district}";
            }
            return location;
        }
    }
}
